package edu.ynu.se.xiecheng.achitectureclass.project.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.*;

@Component
@Slf4j
public class SensorApiClient {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${client.id}")
    private String clientId;

    @Value("${client.secret}")
    private String clientSecret;

    private String accessToken;
    private Date accessTokenExpiry;

    private static final String TOKEN_URL = "https://fbox360.com/idserver/core/connect/token";
    private static final String API_URL = "https://fbox360.com/api/v2/dmon/value/get";

    public List<Map<String, Object>> fetchSensorData(List<String> sensorIds, String boxNo) {
        String token = getAccessToken();
        if (token == null) {
            return Collections.emptyList();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + token);
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("ids", sensorIds);

        String url = UriComponentsBuilder.fromHttpUrl(API_URL)
                .queryParam("boxNo", boxNo)
                .build().toUriString();

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        try {
            ResponseEntity<List<Map<String, Object>>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    requestEntity,
                    new ParameterizedTypeReference<List<Map<String, Object>>>() {}
            );
            log.info("响应数据：", response.getBody());
            return response.getBody();
        } catch (HttpClientErrorException.BadRequest e) {
            String errorBody = e.getResponseBodyAsString();
            log.info("Bad Request: " , errorBody);
            return Collections.emptyList();
        }
    }


    private synchronized String getAccessToken() {
        if (accessToken == null || accessTokenExpiry == null || accessTokenExpiry.before(new Date())) {
            // 获取新的AccessToken
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("scope", "fbox");
            params.add("client_id", clientId);
            params.add("client_secret", clientSecret);
            params.add("grant_type", "client_credentials");

            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);

            ResponseEntity<Map> response = restTemplate.postForEntity(TOKEN_URL, requestEntity, Map.class);

            if (response.getStatusCode().is2xxSuccessful()) {
                Map<String, Object> responseBody = response.getBody();
                if (responseBody != null) {
                    accessToken = (String) responseBody.get("access_token");
                    Integer expiresIn = (Integer) responseBody.get("expires_in");
                    if (expiresIn != null) {
                        accessTokenExpiry = new Date(System.currentTimeMillis() + expiresIn * 1000L);
                    }
                }
            }
        }
        return accessToken;
    }
}
